﻿using System;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using AvalonDock;
using Foundation;
using Poet.ViewModels;
using MenuItem = System.Windows.Controls.MenuItem;

namespace Poet.Views
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainView
    {
        public static readonly DependencyProperty DisableWindowActivationProperty =
            DependencyProperty.Register("DisableWindowActivation", typeof(Boolean), typeof(TrayWindow), new FrameworkPropertyMetadata(false));

        private HwndSource _hwndSource;

        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            return IntPtr.Zero;

            var isFloating = VisualTreeHelper.GetParent(DockingManager.ActiveContent) == null;
            if (msg == 134 && isFloating  )
            {
                ;
            }

            if (DockingManager.FloatingWindows.Any())
            {
                Trace.WriteLine(DockingManager.FloatingWindows[0]);
            } 

            return IntPtr.Zero;
        }

        protected void AddHookToParentWindow()
        {
            _hwndSource = PresentationSource.FromVisual(this) as HwndSource;  

            if (_hwndSource != null)
            {
                _hwndSource.AddHook(WndProc);
            }

            DockingManager.ActiveContentChanged += (o, e) =>
                {
                    var isFloating = VisualTreeHelper.GetParent(DockingManager.ActiveContent) == null;
                    Helpers.WindowExtensions.ShowAsActive(this, !isFloating);
                };
        }

        public MainView()
        {
            InitializeComponent();
            ThemeFactory.ChangeColors(Colors.Silver);
            //HwndSource.DefaultAcquireHwndFocusInMenuMode = false;
            Keyboard.DefaultRestoreFocusMode = RestoreFocusMode.None;

            var lastFocusedElement = Keyboard.FocusedElement;
            InputManager.Current.EnterMenuMode += delegate { lastFocusedElement = Keyboard.FocusedElement; };
            InputManager.Current.LeaveMenuMode += delegate
                {
                    if (lastFocusedElement != null)
                    {
                        lastFocusedElement.Focus();
                    }
                };
        }

        private void IgnoreGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            e.Handled = true;
        }

        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            AddHookToParentWindow();
            SetBinding(DisableWindowActivationProperty, "DisableWindowActivation");
        }

        public bool DisableWindowActivation
        {
            get
            {
                return (bool)GetValue(DisableWindowActivationProperty);
            }

            set
            {
                SetValue(DisableWindowActivationProperty, value);
            }
        }

        private MainViewModel MainViewModel
        {
            get
            {
                return DataContext as MainViewModel;
            }
        }

        private void DockingManagerPreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            var documentPanes = DockingManager.GetVisualDescendants<DocumentPane>();

            foreach (var pane in documentPanes)
            {
                pane.MouseDoubleClick -= DocumentPaneMouseDoubleClick;
                pane.MouseDoubleClick += DocumentPaneMouseDoubleClick;
            }

            if (DockingManager.Documents.Count == 0 && e.OriginalSource is Border)
            {
                CreateNewOrOpenDocument(e);
            }
        }

        private void DocumentPaneMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (e.OriginalSource is Border)
            {
                DockingManager.MainDocumentPane = (DocumentPane)sender;
                CreateNewOrOpenDocument(e);
            }
        }

        private void CreateNewOrOpenDocument(MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Left)
            {
                ApplicationCommands.New.Execute(null, this);
            }

            if (e.ChangedButton == MouseButton.Right)
            {
                ApplicationCommands.Open.Execute(null, this);
            }    
        }

        private void OnCheckDocumentView(object sender, RoutedEventArgs e)
        {
            var menuItem = (MenuItem)e.OriginalSource;
            var newCheckedDocument = (ManagedContent)menuItem.DataContext;
            newCheckedDocument.Show(DockingManager);
            newCheckedDocument.Activate();
        }

        private void MenuItemClick(object sender, RoutedEventArgs e)
        {
            var menuItem = (MenuItem)sender;
            var tag = (string)menuItem.Tag;
            MenuItemClick(tag);
        }

        private void MenuItemClick(string tag)
        {
            switch (tag)
            {
                case "ShowNavigatorWindow":
                    DockingManager.ShowNavigatorWindow();
                    break;
            }
        }

        private Point LastPosition { get; set; }

        private void DragMove(object sender, MouseEventArgs e)
        {
            var currentPosition = e.GetPosition(this);

            if (e.LeftButton == MouseButtonState.Pressed && currentPosition != LastPosition && !InputManager.Current.IsInMenuMode)
            {
                DragMove();
            }

            LastPosition = currentPosition;
        }

        private void OnCheckWindowStyle(object sender, RoutedEventArgs e)
        {
            var menuItem = (MenuItem)e.OriginalSource;
            MainViewModel.WindowStyle = (WindowStyle)menuItem.DataContext;
            CheckMenuItems(WindowStyleMenu, menuItem);
        }

        private void OnCheckResizeMode(object sender, RoutedEventArgs e)
        {
            var menuItem = (MenuItem)e.OriginalSource;
            MainViewModel.ResizeMode = (ResizeMode)menuItem.DataContext;
            CheckMenuItems(ResizeModeMenu, menuItem);
        }

        private static void CheckMenuItems(ItemsControl parentMenu, MenuItem currentMenuItem)
        {
            foreach (var item in parentMenu.Items)
            {
                var menuItem = (MenuItem)parentMenu.ItemContainerGenerator.ContainerFromItem(item);
                menuItem.IsChecked = false;
            }

            currentMenuItem.IsChecked = true;
        }

        private void ChangeWindowState(object sender, MouseButtonEventArgs e)
        {
            WindowState = WindowState == WindowState.Normal ? WindowState.Maximized : WindowState.Normal;
        }
    }
}
